#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/version.h>
#include<linux/fs.h>
#include<linux/types.h>
#include<linux/kdev_t.h>
#include<linux/device.h>
#include<linux/cdev.h>


static dev_t first;
static struct cdev c_dev;
static struct class *cl;

static int my_open(struct inode *i, struct file *f)
{
  printk(KERN_INFO "Driver: open()\n");
  return 0;
}
  static int my_close(struct inode *i, struct file *f)
{
  printk(KERN_INFO "Driver: close()\n");
  return 0;
}
  static ssize_t my_read(struct file *f, char __user *buf, size_t
  len, loff_t *off)
{
  printk(KERN_INFO "Driver: read()\n");
  return 0;
}
  static ssize_t my_write(struct file *f, const char __user *buf,
  size_t len, loff_t *off)
{
  printk(KERN_INFO "Driver: write()\n");
  return len;
}
  static struct file_operations chd_fops =
{
  .owner = THIS_MODULE,
  .open = my_open,
  .release = my_close,
  .read = my_read,
  .write = my_write
};

static int __init chdinit(void)   /*constructor*/
{
	if (alloc_chrdev_region(&first,0,0,"chardev1") < 0)
	{
		printk( "\n Failed to allocate the character device \n");
		return -1;
	}
	printk( "\n Allocated character device  \n");
	if((cl=class_create(THIS_MODULE,"chardevclass"))==NULL)
	{
		unregister_chrdev_region(first,0);
		return -1;
	}
	
	if(device_create(cl,NULL,first,NULL,"charc")==NULL)
	{
		class_destroy(cl);
		unregister_chrdev_region(first,0);
		return -1;
	}

	cdev_init(&c_dev,&chd_fops);
	if (cdev_add(&c_dev, first, 1) == -1)
  	{
    		device_destroy(cl, first);
		class_destroy(cl);
	        unregister_chrdev_region(first, 1);
	        return -1;
  	}
  	
	return 0;
}

static void __exit chdexit(void)  /*destructor*/
{
	cdev_del(&c_dev);
	device_destroy(cl,first);
	class_destroy(cl);
	unregister_chrdev_region(first,0);
	printk( "\n UNregistered character device  \n");
	
}

module_init(chdinit);
module_exit(chdexit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Krishnendhu Prakasan");
MODULE_DESCRIPTION("Character driver 2");
